package com.shycloud.mido.member.service.impl;

import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.shycloud.mido.common.api.entity.OrganizationCommon;
import com.shycloud.mido.common.api.mapper.OrganizationCommonMapper;
import com.shycloud.mido.common.core.constant.CommonConstants;
import com.shycloud.mido.common.core.constant.SecurityConstants;
import com.shycloud.mido.common.core.constant.enums.LoginTypeEnum;
import com.shycloud.mido.common.core.exception.BusinessException;
import com.shycloud.mido.common.core.util.R;
import com.shycloud.mido.common.security.util.SecurityUtils;
import com.shycloud.mido.member.api.dto.MemberV2DTO;
import com.shycloud.mido.member.api.entity.*;
import com.shycloud.mido.member.api.vo.SmMemberTeacherApprovalNewVO;
import com.shycloud.mido.member.mapper.*;
import com.shycloud.mido.member.service.MemberServiceV2;
import com.shycloud.mido.member.service.MsgMainService;
import com.shycloud.mido.member.service.RegisterService;
import com.shycloud.mido.organ.api.enums.MessageCodeEnum;
import com.shycloud.mido.task.api.entity.SmMemberTask;
import com.shycloud.mido.task.api.feign.RemoteTaskService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 重构会员注册模块
 *
 * @author nianhua.jiang
 */
@Slf4j
@Service
@AllArgsConstructor
public class RegisterServiceImpl implements RegisterService {

	/** 密码解密 */
	private static final PasswordEncoder ENCODER = new BCryptPasswordEncoder();

	/** 会员模块 Mapper */
	private final MemberMapper memberMapper;
	/** 打印活动 mapper */
	private final ErpActivityInfoMapper activityInfoMapper;
	/** 会员详细信息 mapper */
	private final MemberDetailInfoMapper memberDetailInfoMapper;
	/** 会员模块 service */
	private final MemberServiceV2 memberService;
	/** 缓存工具类 */
	private final RedisTemplate redisTemplate;
	/** 任务模块 service */
	private final RemoteTaskService taskService;
	/** 领取分享注册任务记录表 */
	private final SmMemberTaskRecordMapper taskRecordMapper;
	/** 工作室 mapper */
	private final OrganizationCommonMapper organizationCommonMapper;
	/** 教师模块 mapper */
	private final OrgTeacherDetailedMapper teacherDetailedMapper;
	/** 教师认证 mapper */
	private final SmMemberTeacherApprovalNewMapper teacherApprovalMapper;
	/** 后台管理系统 用户 mapper */
	private final SysUserMapper sysUserMapper;
	/** 代理商机构关系模块 mapper */
	private final OptOrgMapper optOrgMapper;
	/** 后台管理系统 用户-角色 mapper */
	private final SysUserRoleMapper sysUserRoleMapper;
	/** 消息模块 mapper */
	private final MsgMemberInfoMapper msgMemberInfoMapper;
	/** 消息主表 service */
	private final MsgMainService msgMainService;
	/** 教师身份 */
	private final String IDENTITY_TEACHER = "1";

	@Override
	public boolean appRegister(Map<String, String> requestMap) {

		// 电话号(账号)
		String phone = requestMap.get("phone");
		// 验证码
		String code = requestMap.get("code");
		//校验验证码
		checkCaptcha(phone, code);
		//手机号已注册
		if (checkMember(phone) != null) {
			throw new BusinessException(
					new R<>(Boolean.FALSE, MessageCodeEnum.MEMBER_ERROR_103.getMessage()));
		} else {
			//注册会员
			MemberV2DTO memberDTO = new MemberV2DTO();
			//电话号
			memberDTO.setPhone(phone);
			//账号
			memberDTO.setUsername(phone);
			//密码
			memberDTO.setPassword(SecurityUtils.DEFAULT_PASSWORD);
			//注册来源 APP
			memberDTO.setRegisterFrom(Member.APP_REGISTER);
			//性别
			memberDTO.setSex("0");

			return addMember(memberDTO) != null;
		}
	}

	@Override
	public String wxRegister(String username, String openId) {

		//获取微信头像及昵称
		String token = redisTemplate.opsForValue().get("wxOpenId_" + openId).toString();

		//根据 token 获取头像，昵称等个人信息
		String url = String.format(SecurityConstants.WX_USER_INFO_URL, token, openId);

		String result = HttpUtil.get(url);
		System.out.println("=========================微信登录响应用户信息:{" + result + "}");

		if (!result.isEmpty()) {
			//注册会员
			MemberV2DTO memberDTO = new MemberV2DTO();
			//电话号
			memberDTO.setPhone(username);
			//账号
			memberDTO.setUsername(username);
			//密码
			memberDTO.setPassword(SecurityUtils.DEFAULT_PASSWORD);
			//注册来源 APP
			memberDTO.setRegisterFrom(Member.WX_REGISTER);
			//微信 openId
			memberDTO.setWxOpenid(openId);
			//昵称
			memberDTO.setShowname(JSONUtil.parseObj(result).get("nickname").toString());
			//性别
			memberDTO.setSex(JSONUtil.parseObj(result).get("sex").toString());
			//头像
			memberDTO.setAvatar(JSONUtil.parseObj(result).get("headimgurl").toString());
			//新增用户
			return addMember(memberDTO).getId();
		} else {
			throw new BusinessException("微信信息获取失败");
		}
	}

	@Override
	public String iosRegister(String appleId, String appleToken) {

		//注册会员
		MemberV2DTO memberDTO = new MemberV2DTO();
		//电话号
		memberDTO.setPhone(appleId);
		//账号
		memberDTO.setUsername(appleId);
		//appleId
		memberDTO.setAppleOpenId(appleId);
		//密码
		memberDTO.setPassword(SecurityUtils.DEFAULT_PASSWORD);
		//注册来源 APP
		memberDTO.setRegisterFrom(Member.IOS_REGISTER);
		//性别
		memberDTO.setSex("0");
		//IOS token
		memberDTO.setAppleToken(appleToken);
		return addMember(memberDTO).getId();
	}

	@Override
	public String syRegister(String username) {

		Member member = checkMember(username);
		if (member != null) {
			return member.getId();
		}
		//注册会员
		MemberV2DTO memberDTO = new MemberV2DTO();
		//电话号
		memberDTO.setPhone(username);
		//账号
		memberDTO.setUsername(username);
		//密码
		memberDTO.setPassword(username);
		//注册来源 APP
		memberDTO.setRegisterFrom(Member.SY_REGISTER);
		//性别
		memberDTO.setSex("0");

		return addMember(memberDTO).getId();
	}

	@Override
	public String wxMiniRegister(String wxOpenId) {

		//注册会员
		MemberV2DTO memberDTO = new MemberV2DTO();
		//电话号
		memberDTO.setPhone(wxOpenId);
		//账号
		memberDTO.setUsername(wxOpenId);
		//密码
		memberDTO.setPassword(SecurityUtils.DEFAULT_PASSWORD);
		//注册来源 APP
		memberDTO.setRegisterFrom(Member.WX_MINI_REGISTER);
		//性别
		memberDTO.setSex("0");
		//昵称
		memberDTO.setShowname("微信临时用户");

		return addMember(memberDTO).getId();
	}

	@Override
	@Transactional
	public String shareRegister(String phone, String code, String fromMemberId, Integer pageId) {

		//校验验证码
		checkCaptcha(phone, code);
		//校验用户
		Member member = checkMember(phone);

		if (member != null) {
			throw new BusinessException("手机号已注册!");
		}

		//注册会员
		MemberV2DTO memberDTO = new MemberV2DTO();
		//电话号
		memberDTO.setPhone(phone);
		//账号
		memberDTO.setUsername(phone);
		//密码
		memberDTO.setPassword(SecurityUtils.DEFAULT_PASSWORD);
		//注册来源 APP
		memberDTO.setRegisterFrom(Member.SHARE_REGISTER);
		//性别
		memberDTO.setSex("0");

		//注册
		String toMemberId = addMember(memberDTO).getId();

		//送会员:固定活动 pageId = 3
		List<SmMemberTask> tasks = taskService.getTaskByPageId(pageId);

		Integer taskId = 0;

		for (SmMemberTask task : tasks) {
			//注册人员领取奖励
			if ("share_to".equals(task.getExpand3())) {
				taskService.receiveAward(task.getId(), toMemberId, "");
			}
			//邀请人员领取奖励
			if ("share_from".equals(task.getExpand3())) {
				taskService.receiveAward(task.getId(), fromMemberId, "");
			}
		}

		// 记录信息
		SmMemberTaskRecord smMemberTaskRecord = new SmMemberTaskRecord();
		//创建时间
		smMemberTaskRecord.setCreateTime(LocalDateTime.now());
		//分享者ID
		smMemberTaskRecord.setFromMemberId(fromMemberId);
		//注册者ID
		smMemberTaskRecord.setToMemberId(toMemberId);
		//活动ID
		smMemberTaskRecord.setTaskId(taskId);
		//新增
		taskRecordMapper.insert(smMemberTaskRecord);
		return toMemberId;
	}

	private String getRewardTypeStr(SmMemberTask task) {

		String rewardType = StringUtils.EMPTY;

		if ("1".equals(task.getRewardType())) {
			rewardType = "VIP会员时长";
		}
		if ("4".equals(task.getRewardType())) {
			rewardType = "快乐贝";
		}
		return rewardType;
	}

	@Override
	public String register(MemberV2DTO memberDTO) {

		//校验手机号
		Member member = checkMember(memberDTO.getPhone());

		if (member != null) {
			throw new BusinessException("手机号重复");
		}

		if (memberDTO.getOptId() == null) {
			memberDTO.setOptId(999999);
		} else {
			memberDTO.setOptId(memberDTO.getOptId());
		}

		memberDTO.setPassword(SecurityUtils.DEFAULT_PASSWORD);
		//设置用户名
		memberDTO.setUsername(memberDTO.getPhone());

		member = addMember(memberDTO);

		//如果为教师身份，则创建工作室
		if (IDENTITY_TEACHER.equals(memberDTO.getIdentity())) {

			//工作室名称为空，返回错误信息
			if (memberDTO.getStudioName().isEmpty()) {
				throw new BusinessException("工作室名称参数错误");
			}

			//在判断工作室名称是否重复
			else {
				List<OrganizationCommon> orgList = organizationCommonMapper.selectList(
						new QueryWrapper<OrganizationCommon>()
								.eq("name", memberDTO.getStudioName()));
				if (orgList.size() > 0) {
					throw new BusinessException("工作室名称重复");
				} else {
					//新建工作室
					OrganizationCommon office = addStudio(memberDTO, member.getId());
					//新增教师信息
					addTeacher(memberDTO, member.getId(), office.getId());
					//新增教师认证表
					addTeacherApproval(memberDTO, member);
					//更新后台角色
					SysUser sysUser = addSysUser(member);
					//插入用户-角色关系表
					addUserRole(sysUser);
					//插入运营商机构关系表
					addOptOrg(memberDTO, office);
				}
			}
		}
		return member.getId();
	}

	/**
	 * 添加运营商可机构关系
	 *
	 * @param memberDTO 用户信息
	 * @param office    工作室信息(机构信息)
	 * @author nianhua.jiang
	 * @date 2021/7/15 17:15
	 */
	private void addOptOrg(MemberV2DTO memberDTO, OrganizationCommon office) {
		OptOrg optOrg = new OptOrg();
		optOrg.setOptId(memberDTO.getOptId());
		optOrg.setOrgId(office.getId());
		optOrgMapper.insert(optOrg);
	}

	/**
	 * 添加用户角色权限
	 *
	 * @param sysUser 系统角色信息
	 * @author nianhua.jiang
	 * @date 2021/7/15 17:16
	 */
	private void addUserRole(SysUser sysUser) {
		SysUserRole sysUserRole = new SysUserRole();
		//userId
		sysUserRole.setUserId(sysUser.getUserId());
		//角色ID - 固定为机构角色
		sysUserRole.setRoleId(19);
		//新增用户角色关系表
		sysUserRoleMapper.insertRole(sysUserRole);
	}

	/**
	 * 添加系统用户
	 *
	 * @param member 用户信息
	 * @author nianhua.jiang
	 * @date 2021/7/15 17:17
	 */
	private SysUser addSysUser(Member member) {
		SysUser sysUser = new SysUser();
		//用户名
		sysUser.setUsername(member.getPhone());
		//密码
		sysUser.setPassword(ENCODER.encode("123456"));
		//手机号码
		sysUser.setPhone(member.getPhone());
		//头像
		sysUser.setAvatar(member.getAvatar());
		//部门ID 固定写死 为 25
		sysUser.setDeptId(25);
		//是否锁定
		sysUser.setLockFlag("0");
		//逻辑删除
		sysUser.setDelFlag("0");
		//创建时间
		sysUser.setCreateTime(new Date());
		//新增后台管理的用户信息
		sysUserMapper.insertSysUser(sysUser);
		return sysUser;
	}

	/**
	 * 新增教师认证表
	 *
	 * @param memberDTO 用户信息
	 * @param member    用户信息
	 * @author nianhua.jiang
	 * @date 2021/7/15 17:13
	 */
	private void addTeacherApproval(MemberV2DTO memberDTO, Member member) {

		SmMemberTeacherApprovalNew teacherApproval = new SmMemberTeacherApprovalNewVO();
		//状态：已通过
		teacherApproval.setStatus("1");
		//电话号码
		teacherApproval.setPhone(member.getPhone());
		//用户ID
		teacherApproval.setMemberId(member.getId());
		//教师姓名
		teacherApproval.setName(memberDTO.getShowname());
		//省编号
		teacherApproval.setProvinceCode(memberDTO.getProvinceCode());
		//省名称
		teacherApproval.setProvinceName(memberDTO.getProvince());
		//市编号
		teacherApproval.setCityCode(memberDTO.getCityCode());
		//市名称
		teacherApproval.setCityName(memberDTO.getCity());
		//工作室名称
		teacherApproval.setStudioName(memberDTO.getStudioName());
		//创建时间
		teacherApproval.setCreateTime(new Date());

		teacherApprovalMapper.insert(teacherApproval);
	}

	/**
	 * 新增教师详情
	 *
	 * @param memberDTO 用户信息
	 * @param memberId  用户ID
	 * @param officeId  工作室ID
	 * @author nianhua.jiang
	 * @date 2021/7/15 17:11
	 */
	private void addTeacher(MemberV2DTO memberDTO, String memberId, Integer officeId) {
		//新增教师详情
		OrgTeacherDetailed orgTeacherDetailed = new OrgTeacherDetailed();
		//用户ID
		orgTeacherDetailed.setMemberId(memberId);
		//创建时间
		orgTeacherDetailed.setCreateTime(new Date());
		//教师姓名
		orgTeacherDetailed.setName(memberDTO.getShowname());
		//教师机构ID
		orgTeacherDetailed.setOrgId(officeId);

		teacherDetailedMapper.insert(orgTeacherDetailed);
	}

	/**
	 * 新建工作室
	 *
	 * @param memberDTO 用户信息
	 * @param memberId  用户ID
	 * @author nianhua.jiang
	 * @date 2021/7/15 17:08
	 */
	private OrganizationCommon addStudio(MemberV2DTO memberDTO, String memberId) {

		OrganizationCommon office = new OrganizationCommon();
		office.setProvince(memberDTO.getProvince());
		office.setCity(memberDTO.getCity());
		//创建时间
		office.setCreateTime(new Date());
		//创建者
		office.setCreateUser(memberId);
		//在线陪练 -> 开通
		office.setAccompany("1");
		//状态 -> 启用
		office.setStatus("0");
		//工作室
		office.setIsStudio("1");
		office.setTag(memberDTO.getTag());
		//电话号码
		office.setPhone(memberDTO.getPhone());
		//工作室名称
		office.setName(memberDTO.getStudioName());
		//密码：用户密码
		office.setPsw(ENCODER.encode(SecurityUtils.DEFAULT_PASSWORD));
		//机构码
		office.setCode(memberService.getCode());
		//新增
		organizationCommonMapper.insert(office);
		return office;
	}

	/**
	 * 注册会员
	 *
	 * @param memberDTO 用户信息体
	 * @return java.lang.String
	 * @author nianhua.jiang
	 * @date 2020/6/27 11:06
	 */
	private Member addMember(MemberV2DTO memberDTO) {

		//注册会员
		Member member = new Member();
		//copy数据
		BeanUtils.copyProperties(memberDTO, member);

		//账号ID
		member.setAccount(memberService.getAccount());
		//用户身份
		member.setIsTeacher(
				org.apache.commons.lang.StringUtils.isEmpty(memberDTO.getIdentity()) ? "0"
						: memberDTO.getIdentity());

		//IOS注册
		if (Member.IOS_REGISTER.equals(memberDTO.getRegisterFrom())) {
			member.setPhone(memberService.getAccount());
			//用户名（手机号）
			member.setUsername(memberService.getAccount());
		}
		//上音社合作注册
		else if (Member.SY_REGISTER.equals(memberDTO.getRegisterFrom())) {
			//TODO 上音社合作注册(冗余字段) - 涉及业务:后台管理首页数据统计逻辑
			member.setIsOld("3");
		}

		if (memberDTO.getShowname() == null) {
			//昵称（宝贝+手机号后四位）
			member.setShowname("宝贝" + memberDTO.getPhone().substring(memberDTO.getPhone().length() - 4, memberDTO.getPhone().length()));
		} else {
			member.setShowname(memberDTO.getShowname());
		}

		//密码
		member.setPassword(ENCODER.encode(memberDTO.getPassword()));
		//创建时间z
		member.setCreateTime(LocalDateTime.now());
		//逻辑删除
		member.setDelFlag(CommonConstants.STATUS_NORMAL);
		//未锁定
		member.setLockFlag("0");
		//打印次数
		member.setPrintAmountGive(getPrintCount());
		//新增会员
		memberMapper.insert(member);
		//新增用户详情
		addMemberDetailInfo(member, memberDTO.getSex());

		//新业务：注册送 30 天会员
		taskService.receiveAward(11, member.getId(), "");
  
		taskService.receiveAward(13, member.getId(), "");
  
		//返回用户ID
		return member;

	}

	/**
	 * 校验验证码
	 *
	 * @param phone 电话号
	 * @param code  验证码
	 * @author nianhua.jiang
	 * @date 2021/7/15 9:15
	 */
	private void checkCaptcha(String phone, String code) {
		// 初始化定义超级验证码
		String superCaptcha = StringUtils.EMPTY;

		// 获取超级验证码
		Object superCodeObj = redisTemplate.opsForValue().get("superCaptcha");
		if (superCodeObj == null) {
			log.info("超级验证码已过期:{}", phone);
		} else {
			superCaptcha = superCodeObj.toString();
		}

		// 校验超级验证码
		if (superCaptcha.isEmpty() || !code.equals(superCaptcha)) {

			// 校验验证码
			Object codeObj = redisTemplate.opsForValue()
					.get(CommonConstants.DEFAULT_CODE_KEY + LoginTypeEnum.SMS.getType() + "@"
							+ phone);
			// 验证码已过期
			if (codeObj == null) {
				throw new BusinessException(
						new R<>(Boolean.FALSE, MessageCodeEnum.MEMBER_ERROR_104.getMessage())
								.setCode(MessageCodeEnum.MEMBER_ERROR_104.getCode()));
			}
			// 验证码错误
			else if (!code.equals(codeObj.toString())) {
				throw new BusinessException(
						new R<>(Boolean.FALSE, MessageCodeEnum.MEMBER_ERROR_105.getMessage())
								.setCode(MessageCodeEnum.MEMBER_ERROR_105.getCode()));
			}
		}
	}

	/**
	 * 检查手机号对应用户是否存在
	 *
	 * @param username 用户账号/手机号
	 * @return true-存在  false-不存在
	 * @author nianhua.jiang
	 * @date 2021/7/14 16:01
	 */
	private Member checkMember(String username) {
		return memberMapper.selectOne(new QueryWrapper<Member>()
				.eq("username", username)
				.eq("del_flag", CommonConstants.STATUS_NORMAL));
	}

	/**
	 * 获取免费打印次数
	 *
	 * @return 打印次数
	 * @author nianhua.jiang
	 * @date 2021/7/14 16:24
	 */
	private int getPrintCount() {

		//是否有注册送打印次数的活动
		List<ErpActivityInfo> erpActivityInfos = activityInfoMapper
				.selectList(new QueryWrapper<ErpActivityInfo>()
						//注册送打印次数
						.eq(ErpActivityInfo.COL_TYPE, "1")
						//状态为激活
						.and(x -> x.eq(ErpActivityInfo.COL_IS_ENABLED, "1")));
		//打印次数
		int printCount = 0;

		for (ErpActivityInfo erpActivityInfo : erpActivityInfos) {
			printCount += erpActivityInfo.getFreeAmount();
		}
		return printCount;
	}

	/**
	 * 新增 member 详情
	 *
	 * @param member 用户信息
	 * @param sex    性别
	 * @return
	 * @author nianhua.jiang
	 * @date 2021/7/14 16:26
	 */
	private void addMemberDetailInfo(Member member, String sex) {

		MemberDetailInfo memberDetailInfo = new MemberDetailInfo();
		//默认性别：男
		memberDetailInfo.setSex(sex);
		//memberId
		memberDetailInfo.setMemberId(member.getId());
		//默认出生日期：2010-01-01
		memberDetailInfo.setBirthday("2010-01-01");

		memberDetailInfoMapper.insert(memberDetailInfo);
	}

	private String addMsg(String title, String message) {

		MsgMain msgMain = new MsgMain();
		//给教师或者学生发送
		msgMain.setTriggerTo("4");
		//来自分享注册活动奖励通知 - 系统自动推送
		msgMain.setTriggerFrom("0");
		//消息下发的场合：活动奖励领取
		msgMain.setPoint("7");
		//不可修改
		msgMain.setModify("0");
		//自动推送
		msgMain.setMode("1");
		//个人
		msgMain.setRangeType("1");
		//有效数据
		msgMain.setDelFlag("0");
		//创建时间
		msgMain.setCreateTime(LocalDateTime.now());
		//消息类型：文本
		msgMain.setMsgType("0");
		//发送时间
		msgMain.setActualPubDatetime(LocalDateTime.now());
		//创建人-> 系统
		msgMain.setCreateUser("sys");
		//消息内容
		msgMain.setMessage(message);
		//发布时间
		msgMain.setPubDatetime(LocalDateTime.now());
		//推送成功
		msgMain.setPushStatus("0");
		//推送时间
		msgMain.setPushTime(LocalDateTime.now());
		//标题
		msgMain.setTitle(title);
		//系统消息
		msgMain.setType("0");

		return msgMainService.addSysMsg(msgMain);
	}

}
